using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using System.Collections.Generic;

namespace IQIGame.Onigao.Logic
{
    public class LevelService : IReusableClass
    {
        /// <summary>
        /// 服务触发器
        /// </summary>
        private BaseServiceTrigger _trigger;
        /// <summary>
        /// 服务单元
        /// </summary>
        private List<LevelServiceUnit> _serviceUnits = new List<LevelServiceUnit>();
        /// <summary>
        /// 是否触发过执行，用于判断是否是被再利用的pool对象，详情请见调用处
        /// </summary>
        private bool _executed = false;

        public LevelServiceConfig config { get; private set; }
        public ServiceTriggerType triggerType => config.triggerType;

        public BaseLevelFunctionHost host { get; private set; }

        public uint MaxStore => 50;

        public void Init(int serviceCid, BaseLevelFunctionHost host)
        {
            if (!host.region.gameplayConfig.services.TryGetValue(serviceCid, out var cfg))
            {
                LogicLog.LogError($"关卡配置里找不到服务. Service id: {serviceCid}");
                return;
            }
            this.config = cfg;
            this.host = host;
            InitTrigger();
            InitUnits();
        }

        /// <summary>
        /// 初始化触发器
        /// </summary>
        private void InitTrigger()
        {
            if (config.triggerType > 0)
            {
                _trigger = ServiceFactory.CreateTrigger(triggerType);
                if (_trigger != null)
                {
                    _trigger.Init(config.triggerParam);
                    _trigger.SetData(this, host);
                }
            }
        }

        public ServiceTriggerType GetTriggerType()
        {
            return _trigger == null ? ServiceTriggerType.None : triggerType;
        }

        /// <summary>
        /// 初始化执行
        /// </summary>
        private void InitUnits()
        {
            for (int i = 0; i < config.serviceUnits.Count; i++)
            {
                var unitConfig = config.serviceUnits[i];
                LevelServiceUnit unit = ClassPool.Get<LevelServiceUnit>();
                unit.Init(config.id, i, unitConfig, host);
                _serviceUnits.Add(unit);
            }
        }

        /// <summary>
        /// 触发
        /// </summary>
        /// <param name="player"></param>
        /// <param name="dynamicObjPram"></param>
        /// <param name="dynamicValueTypePram"></param>
        /// <returns>是否有任意执行成功生效</returns>
        public bool TryTrigger(LevelPlayer player, object dynamicObjPram, TrigValueTypeParam dynamicValueTypePram)
        {
            if (GetTriggerType() == ServiceTriggerType.None) //触发类型为空，不响应任何触发，只适用于强制执行的服务
                return false;
            return _trigger.OnTrigger(player, dynamicObjPram, dynamicValueTypePram);
        }

        public int Execute(LevelPlayer player)
        {
            _executed = true;
            int successExecCount = 0;
            List<LevelServiceUnit> tempUnitList = ListPool<LevelServiceUnit>.Get();
            {
                tempUnitList.AddRange(_serviceUnits);
                foreach (LevelServiceUnit unit in tempUnitList)
                {
                    successExecCount += LevelServiceModule.ExecUnit(player, unit, true, out bool needBreak);
                    if (needBreak)
                    {
                        break;
                    }
                    //执行过程中，可能会销毁当前服务（如：替换服务），后续执行作废
                    //服务被销毁后，_executed会被重置为false
                    //不能通过如cfgData == null来判断服务是否在执行过程中被销毁，因为它在销毁后可能会从对象池中被取出，变成新的服务。
                    //但_executed不同，它只会在触发执行后改变，而新服务不可能在旧服务执行过程中触发执行
                    if (!_executed)
                    {
                        break;
                    }
                }
                ListPool<LevelServiceUnit>.Put(tempUnitList);
            }
            return successExecCount;
        }

        public void SetUnitEnabled(int unitIndex, bool isEnabled)
        {
            if (unitIndex < 0 || unitIndex >= _serviceUnits.Count)
            {
                LogicLog.LogError($"开关服务单元失败，index {unitIndex} 非法, 服务单元列表长度：{_serviceUnits.Count}。");
                return;
            }
            var unit = _serviceUnits[unitIndex];
            unit.disabled = !isEnabled;
        }

        public void OnReset()
        {
            config = null;
            //注意这里ClassPool.Put
            //由于本类中trigger和execution都是以基类类型存储的，参数都必须以IReusableClass类型传入，确保被正确的Put到对应池子里
            //否则将调用到泛型方法，放入错误的池子（基类类型，实际上没有这个池子）
            ClassPool.PutAutoType(_trigger);
            _trigger = null;
            foreach (LevelServiceUnit unit in _serviceUnits)
            {
                ClassPool.Put(unit);
            }
            _serviceUnits.Clear();
            _executed = false;
            host = null;
        }
    }
}
